#!/bin/dash
# This is an installation script for auto installing additional support for
# FSC laptops Amilo A16xx
# Written by Assaf Paz (damagedspline@aim.com || damagedspline@gmail.com)

SUCCESS=1
CURRENT_DIR=$(pwd)
KERNEL_VER=$(uname -r)
AR5005G_OPTION="options ath_pci rfkill=0"
PACKAGES_UPDATED=FALSE
SCRIPT_VER=0.6.3
INSTALL_DIR=/usr/local/src
LATEST_ATHEROS="http://snapshots.madwifi.org/madwifi-hal-0.10.5.6-current.tar.gz"
ACERHK_HASH="97EB47F12529D73FE215F47"
DEBIAN_KEY="A70DAF536070D3A1"

[ "$DEBUG_SCRIPT" = "TRUE" ] && set -x

printMessage()
{
    echo "\033[1m$1\033[0m"
}

checkVersion ()
{
    #check ubuntu version
    if [ -n "$(grep -i 7.10 /etc/issue)" ]; then
    	LINUX_VER=Gutsy
    else if [ -n "$(grep -i 7.04 /etc/issue)" ]; then
    	    LINUX_VER=Fiesty
	else if [ -n "$(grep -i celina /etc/issue)" ]; then
                LINUX_VER=Celina
	     else if [ -n "$(grep -i hardy /etc/issue)" -o -n "$(grep -i 8.04 /etc/issue)" -o -n "$(grep -i elyssa /etc/issue)" ]; then
			LINUX_VER=Hardy	
		else if [ -n "$(grep -i intrepid /etc/issue)" -o -n "$(grep -i 8.10 /etc/issue)" ]; then
			LINUX_VER=Intrepid
		     else
			printMessage "Error: Linux version is unsupported. This script will only work on Ubuntu 7.04 <= ver or Linux Mint Celina"
			return 1
		     fi
		fi
	     fi
	fi
    fi
    return 0
}

#check the arch
checkArch()
{
    if [ "$(uname -m)" != "i686" ]; then
	printMessage "Error: Sorry, for now this script will only work on 32bit systems"
	return 1
    fi
    return 0
}

#check laptop model
checkModel()
{
    if [ -z "$(grep -i a1650g /var/lib/acpi-support/system-product-name)" ]; then
	if [ -z "$(grep -i 1718 /var/lib/acpi-support/system-product-name)"]; then
	    printMessage "Could not detect Amilo A1650G or LI1718."    
	    if [ -z "$(dpkg --list acpi-support | grep ^ii)" ]; then
		printMessage "Probably caused because acpi-support is missing. Trying to reinstall..."	    
		installPackagesIfNeeded acpi-support
		return checkModel
	    else
		printMessage "Error: Sorry, for now this script is only intended for Amilo A1650G && LI1718"
	    fi
	    return 1
	else
	    ACERHK_OPTION="options acerhk force_series=6805 autowlan=1"
	    MODEL="LI1718"
	fi
    else
	ACERHK_OPTION="options acerhk autowlan=1"
	MODEL="A1650G"
    fi
    return 0
}

#print the welcome message
printWelcome()
{
    printMessage "Welcome to the Fujitsu-Siemens Amilo A16xx automated patch for Ubuntu $LINUX_VER"
    echo ;
    printMessage "This script will enable some of the laptop features such as the Special buttons:"
    printMessage "Wireless, Browser and Fancy Fan"
    echo ;
    return 0
}

#check superuser
checkSuperUser()
{
    if [ ! $(id -u) = 0 ]; then
	printMessage "Error: To run this script, one must be with root privileges. Rerun this script prefixed by sudo"
	return 1
    fi
    return 0
}

#check that all of the needed prerequisits are met
checkPrerequisits()
{
    checkVersion && \
    checkArch && \
    checkModel && \
    checkSuperUser || return 1
    
    return 0
}

#print predefined error message
printError()
{
        case "$1" in
                setup)
                        printMessage "Missing some required files... I you haven't run the setup yet, you should. If you have, you should try remove and run setup again."
                        ;;
                already)
                        printMessage "fscamiloa16xx has already been setup, nothing to do."
                        ;;
                download)
                        printMessage "Error: Unable to download file $2"
                        ;;
                ndiswrapper)
                        printMessage "Error: ndisdriver driver installation failed, setup will continue non-the-less but wireless is not likely to work...;"
			printMessage "Error:...please try to install the driver manually using 'sudo ndiswrapper -i <driver inf file name>'"                 ;;
        esac
        return 0;
}

#install the given packages if needed
installPackagesIfNeeded()
{
        for package in $*; do
                if [ -z "$(dpkg --list $package | grep ^ii)" ]; then
	                if [ "$PACKAGES_UPDATED" = "FALSE" ]; then
		                printMessage "Updating package lists. This may take a while..."
		                if ! apt-get update > /dev/null ; then
			               printMessage "Error: Unable to update package lists... Probably won't be able install packages either..."
			                return 1
		                fi
                                PACKAGES_UPDATED=TRUE
	                fi
                        printMessage "Installing required package: $package"
	                if ! apt-get -qy install $package ; then
		                printMessage "Error: Unable to install required package $package"
		                return 1 
	                fi
                fi
        done
        return 0
}

#add a given line ($1) into a given file ($2)
addLineToFile()
{
	cp $2 $2.part1
        echo $1 > $2.part2
	cat $2.part1 $2.part2 > $2
	rm -f $2.part1 $2.part2
        return 0
}

#blacklist a given module ($1) if not already been blacklisted
blacklistModule()
{
        printMessage "Blacklisting $1"
        if [ -z "$(cat /etc/modprobe.d/blacklist | grep $1)" ]; then
                addLineToFile "blacklist $1" /etc/modprobe.d/blacklist
                if [ -n "lsmod |grep $1" ]; then
	                rmmod "$1"
                fi
        fi
        #check for successful blacklisting
        if [ -z "$(cat /etc/modprobe.d/blacklist | grep $1)" ]; then
                printMessage "Error: Blacklisting of $1 failed. You should manually add \"blacklist $1\" to /etc/modprobe.d/blacklist"
                printMessage "Please report this error to damagedspline@google.com"     
        fi
        return 0
}

#unblacklist a given module ($1) if was blacklisted
unblacklistModule()
{
        printMessage "UnBlacklisting $1"
        if [ -z "$(cat /etc/modprobe.d/blacklist | grep $1)" ]; then
		grep -v $1 /etc/modprobe.d/blacklist > blacklist.fsc
		mv blacklist.fsc /etc/modprobe.d/blacklist
        fi
        return 0
}

#do not load a given module ($1) if was previously set to load
unsetLoadModule()
{
        printMessage "Unsetting module load for $1"
        if [ -z "$(cat /etc/options | grep $1)" ]; then
		grep -v $1 /etc/options > options.fsc
		mv options.fsc /etc/options
        fi
        return 0
}

#setup the machine - $1 = setup/check/remove
doSetup()
{
	cd $INSTALL_DIR

        if [ "$1" = "setup" ]; then
                cp $CURRENT_DIR/$0 /etc/init.d 
                if [ -e /etc/rc5.d/S99fsca16xx ]; then
                        sudo update-rc.d -f fsca16xx.sh remove              
                fi
                sudo update-rc.d fsca16xx.sh defaults
		if [ ! -d fsca16xx ]; then
			if [ "$1" = "check" ]; then
		                printError setup
		                return 1
		        fi
		        mkdir fsca16xx
		fi
		cp /etc/modules $INSTALL_DIR/fsca16xx/modules.bak
		cp /etc/modprobe.d/options $INSTALL_DIR/fsca16xx/options.bak
		cp /etc/modprobe.d/blacklist $INSTALL_DIR/fsca16xx/blacklist.bak
		cp /usr/lib/pm-utils/defaults $INSTALL_DIR/fsca16xx/defaults.bak
		cp /etc/modprobe.d/alsa-base $INSTALL_DIR/fsca16xx/alsa-base.bak
        fi

        cd fsca16xx

        if [ "$1" = "remove" ]; then
                rm -f /etc/rc5.d/S99fsca16xx
                sudo update-rc.d -f fsca16xx.sh remove
                rm -f /etc/acpi/fsc-cpuspeed.sh
                rm -f /etc/acpi/fsc-wireless.sh
                rm -f /usr/share/hotkeys/fsca16xx.def
                rm -f /usr/share/gnome/autostart/hotkeys.desktop
                rm -f /etc/init.d/fsca16xx.sh
		mv $INSTALL_DIR/fsca16xx/modules.bak /etc/modules 
		mv $INSTALL_DIR/fsca16xx/options.bak /etc/modprobe.d/options
		mv $INSTALL_DIR/fsca16xx/blacklist.bak /etc/modprobe.d/blacklist 
		mv $INSTALL_DIR/fsca16xx/defaults.bak /usr/lib/pm-utils/defaults
		mv $INSTALL_DIR/fsca16xx/alsa-base.bak /etc/modprobe.d/alsa-base 
		rm -Rf $INSTALL_DIR/fsca16xx                
		return 0
        fi

        if [ -z "$(modinfo acerhk | grep $ACERHK_HASH)" -a ! "$LINUX_VER" = "Intrepid" ]; then
        	if [ ! -d acerhk-0.5.35 ]; then
                        if [ "$1" = "check" ]; then
                                printError setup
                                return 1
                        fi

		        printMessage "Trying to download precompiled kernel module for Special Buttons"
		        if ! wget -q http://fscamiloa16xx.googlecode.com/svn/trunk/$LINUX_VER/$KERNEL_VER/acerhk.ko; then
			        printMessage "Warning: No precompiled modules for $KERNEL_VER, trying to recompile"
			        if [ ! -e acerhk-current.tgz ]; then 			
				        if ! wget -q http://freshmeat.net/redir/acerhk/30497/url_tgz/acerhk-current.tgz; then
					        printMessage "Error: Unable to download acerhk source code"
					        exit 1
				        fi
				        printMessage "AcerHK source code downloaded successfully"
			        fi
			        tar xzf acerhk-current.tgz
			        if ! cd acerhk-0.5.35; then
				        printMessage "Error: Something wrong with downloaded AcerHK, try manual download of acerhk 0.5.35 and place it under /usr/src/fsca16xx/"
				        exit 1
			        fi
			        if ! wget -q http://fscamiloa16xx.googlecode.com/svn/trunk/acerhk-0.5.35-FSC-AMILO_A16xx.patch; then 
				        printMessage "Error: Unable to retrieve acerhk patch"
			        fi
			        printMessage "Patching AcerHK"
			        patch -i acerhk-0.5.35-FSC-AMILO_A16xx.patch
			        printMessage "Installing required kernel module building tools - this may take a while..."
			        if ! installPackagesIfNeeded build-essential linux-headers-generic ; then
				        return 1 
			        fi
                                printMessage "Compiling AcerHK"
			        if make > ../compile.log ; then
				       printMessage "Compile ended successfully!"
				        mv acerhk.ko ../
				        cd ..
			        else
                                        cd ..
				        printMessage "Error: AcerHK compile failed, compile log can be found at $(pwd)/compile.log"
			        fi
		        else
			        printMessage "Success"
                        fi
                else
                        cd acerhk-0.5.35
                        printMessage "Compiling AcerHK"
			if make > ../compile.log ; then
			        printMessage "Compile ended successfully!"
			        mv acerhk.ko ../
			        cd ..
		        else
                                cd ..
			        printMessage "Error: AcerHK compile failed, compile log can be found at $(pwd)/compile.log"
		        fi
		fi
	        printMessage "Replacing Acerhk module"
	        ACERHK_PATH="$(find /lib/modules/$(uname -r) |grep -m 1 acerhk)"
	        mv -uf acerhk.ko $ACERHK_PATH
	        cd ..
        fi

        if [ ! "$1" = check ]; then
                printMessage "Downloading additional files required by setup"
                if [ ! -e fsc-cpuspeed.sh  ]; then
	                wget -q http://fscamiloa16xx.googlecode.com/svn/trunk/$LINUX_VER/fsc-cpuspeed.sh
                fi
                if [ ! -e fsc-wireless.sh  ]; then
	                wget -q http://fscamiloa16xx.googlecode.com/svn/trunk/$LINUX_VER/fsc-wireless.sh
                fi
                chmod 755 *.sh
                if [ ! -e fsca16xx.def ]; then
	                wget -q http://fscamiloa16xx.googlecode.com/svn/trunk/$LINUX_VER/fsca16xx.def
                fi
                if [ ! -e hotkeys.desktop ]; then
	                wget -q http://fscamiloa16xx.googlecode.com/svn/trunk/$LINUX_VER/hotkeys.desktop
                fi
        fi
        
        if [ "$1" = check ]; then
                echo 1 > /proc/driver/acerhk/wirelessled
        fi

        if ! installPackagesIfNeeded hotkeys libnotify-bin ; then
	        return 1
        fi

	if [ ! "$1" = check ]; then
		printMessage "Setting all features to auto-activate on startup"
		cp -uf *.sh /etc/acpi/
		cp -uf fsca16xx.def /usr/share/hotkeys/
		cp -uf hotkeys.desktop /usr/share/gnome/autostart/
	fi

        printMessage "Adding kernel support for Special Buttons"
	if [ -z "$(grep acerhk /etc/modules)" ]; then
	        addLineToFile acerhk /etc/modules	
        fi
        if [ -z "$(grep acerhk /etc/modprobe.d/options)" ]; then
	        addLineToFile "$ACERHK_OPTION" /etc/modprobe.d/options
        else
	        if [ "$(grep acerhk /etc/modprobe.d/options)" != "$ACERHK_OPTION" ]; then
		        grep -v acerhk /etc/modprobe.d/options > options.fsc
		        addLineToFile "$ACERHK_OPTION" options.fsc
			mv options.fsc /etc/modprobe.d/options  
	        fi
        fi

        #wireless driver section
        if [ -n "$(lspci |grep -i atheros)" -a ! "$LINUX_VER" = "Intrepid" ]; then
		unblacklistModule ath_pci
		unsetLoadModule ndiswrapper
		printMessage "Installing latest Atheros opensource driver"		

		if [ "LI1718" = $MODEL ]; then
	                printMessage "Blacklisting some modules"
			
	                #blacklist netathr
			blacklistModule netathr

			#blacklist sis163u
			blacklistModule sis163u
		fi
		if [ "Hardy" = $LINUX_VER -a -z "$(grep -e SUSPEND_MODULES -e ath_pci /usr/lib/pm-utils/defaults)" ]; then
			mv /usr/lib/pm-utils/defaults defaults.fsc
			cat defaults.fsc | sed 's/\#*\s*\(SUSPEND_MODULES=\"\)\(.*\)\(\"\)/\1ath_pci \2\3/' > /usr/lib/pm-utils/defaults
			rm -f defaults.fsc
		fi
		if [ ! "$1" = check ]; then
			rm -Rf madwifi* 
			wget -c $LATEST_ATHEROS
			tar xvzf madwifi*
			cd madwifi*/
			make
			echo "r" > answer.fsc
			sudo make install < answer.fsc
			sudo rmmod ath_pci ath_rate_sample ath_hal wlan_scan_sta wlan 
			sudo modprobe ath_pci
		fi
        fi

	if [ -n "$(lspci |grep -i atheros)" -a "$LINUX_VER" = "Intrepid" ]; then
		if ! installPackagesIfNeeded linux-backports-modules-intrepid ; then
			return 1
		fi
		blacklistModule ath_pci
	fi

        if [ "Celina" = $LINUX_VER ]; then
                if ! installPackagesIfNeeded wifi-radar ; then
	                return 1
                fi    
        fi        

        #audio section	
        if [ "LI1718" = $MODEL ]; then
                case $LINUX_VER in
                        Fiesty)
	                        if [ -z "$(grep snd-hda-intel /etc/modprobe.d/alsa-base)" ]; then 
		                        printMessage "Fix audio issue"
		                        addLineToFile "options snd-hda-intel index=0 model=3stack" /etc/modprobe.d/alsa-base
	                        fi
                                ;;
                        Celena)
                                if [ -z "$(grep snd-hda-intel /etc/modprobe.d/alsa-base)" ]; then 
		                        printMessage "Fix audio issue"
		                        addLineToFile "options snd-hda-intel index=0 model=3stack" /etc/modprobe.d/alsa-base
	                        fi
                                wget http://homepage.ntlworld.com/roadrash/laptop/alsaconf
                                cp alsaconf /usr/sbin/
                                ;;
			Hardy)
                                if [ -z "$(grep snd-hda-intel /etc/modprobe.d/alsa-base)" ]; then 
		                        printMessage "Fix audio issue"
		                        addLineToFile "options snd-hda-intel index=0 model=toshiba" /etc/modprobe.d/alsa-base
	                        fi
                                ;;
                        *)
                                ;;
                esac
        fi 

        printMessage "Loading kernel modules for Special Buttons"
        if [ -n "$(lsmod |grep acerhk)" ]; then
	        rmmod acerhk
        fi
        modprobe acerhk

        printMessage "Done. Please logout and relogin in order to start using the hotkeys."
        cd $CURRENT_DIR
        return 0
}

# Define LSB log_* functions.
# Depend on lsb-base (>= 3.0-6) to ensure that this file is present.
. /lib/lsb/init-functions

if ! checkPrerequisits ; then
        exit 3        
fi

case "$1" in
  start)
        log_daemon_msg "Checking for proper configuration for Fujistu-Siemens laptops"
	if ! doSetup check ; then
                log_end_msg 1        
        fi
        log_end_msg 0
	;;
  stop)
        #nothing to do
	;;
  setup) 
        printWelcome
	if ! doSetup setup ; then
                exit 3        
        fi
	# nothing to do
	;;    
  remove)
        if ! doSetup remove ; then
                exit 3
        fi 
        ;;
  *)
	printMessage "Usage: $0 {start|stop|setup|remove}"
	exit 3
	;;
esac

:
